/**
 * assignedHomework.js
 * 获取布置作业的相关数据
 *
 * created by muming
 * version 1.0.1
 * 2016年04月15日
 */

import * as CONSTANTS from '../../constants/API';
import rp from '../requestProxy';
import DataAccessor, { ENUM_TIME_UNIT, ENUM_DATA_TYPE } from '../dao/DataAccessor';
import { HTTP_RESULT } from '../../constants/protocol';
import { REPLY_DATA } from '../../constants/replyData';
import cloneDeep from 'lodash/cloneDeep';

// 表名
const HOMEWORK = 'homework',						// 作业表
	  QUESTION = 'homeworkquestion',				// 问题表
	  TEACHER = 'teacher';							// 老师表

// 字段名
const COUNT = 'count',								// 作业数量
	  DIFFICULTY = 'difficulty',					// 作业难度
	  TYPE = 'subjective_count',					// 题型分布
	  DAY = 'day',									// 布置周期
	  HOUR = 'hour';								// 布置时段

const url = `${CONSTANTS.HOST}${CONSTANTS.DATA_PACKAGE_ON_SERVER}`;

/**
 * 打包基础数据
 * @private
 * @param  {String} areaName       地域名称
 * @param  {String} parentAreaName 上级地域名称
 * @param  {Number} timespan	   时间跨度
 * @param  {Array}  data           数据集合
 * @return {Array}                 二维数组
 */
function packageListData (areaName, parentAreaName, timespan, data) {
	// 截取基础数据
	data = data.slice(0, 3).concat(data.slice(6, 9));

	data = data.map((item) => item[0].result? item[0].result: 0);
	let [teachers, homework, list, parentTeachers, parentHomework, parentList] = data;

	let frequency = Math.round(homework / teachers / timespan * 7),
		average = Math.round(list / homework),
		parentFrequency = Math.round(parentHomework / parentTeachers / timespan * 7),
		parentAverage = Math.round(parentList / parentHomework);

	// 判断教师数与作业数是否为空
	if(!teachers || !homework)
		frequency = average = 0;
	if(!parentTeachers || !parentHomework)
		parentFrequency = parentAverage = 0;

	return [[areaName, teachers, homework, list, frequency, average], [parentAreaName, parentTeachers, parentHomework, parentList, parentFrequency, parentAverage]];
}

/**
 * 打包详情数据
 * @private
 * @param     {String}                 areaName 地域名
 * @param     {Number}                 timespan 时间跨度
 * @param     {String}                 data     数据集合
 * @return    {Promise}                         打包数据
 */
function packageDetail (timespan, data) {
	let [teachers, homework, count, difficulty, type, day, hour, question] = data;

	// [areaName, teachers, homework, average, frequency, difficulty, type]
	let result = [];

	/**
	 * 补全并计算四种难度占比
	 */
	function countDifficultyScale(difficulty) {
		// 通过countyId或schoolId区分，并补全
		let addressArray = [];
		let diffArray = [];
		let dArray = [];
		let result = [];

		difficulty.forEach((item) => {
			if(!addressArray.includes(item.multi_data)) addressArray.push(item.multi_data);
		});

		addressArray.forEach((item, index) => {
			diffArray[index] = difficulty.filter((n) => n.multi_data === item);
			dArray[index] = [];
			for(var i = 1; i <= 4; i++) {
				dArray[index].push({
					difficulty: i,
					result: 0
				});
			}
		});

		// 剔除multi_data=0的数据，并补全
		diffArray.forEach((item, index) => diffArray[index] = item.filter((childItem) => childItem.multi_data_ex !== '0'));
		dArray.forEach((item, index) => {
			diffArray[index].forEach((childItem) => {
				let i = Number(childItem.multi_data_ex);
				item[i - 1].result = Number(childItem.result);
			});
		});
		
		/**
		 * 计算难度比例分布
		 */
		function scale (arr) {
			arr = arr.reverse();
	        let scale;
	        return arr.map((item, index) => item.result ? (scale ? item.result / scale : (index === arr.length - 1 ? item.result : (scale = item.result) / scale)) : 0);
	    };
		dArray.forEach((item) => {
			result.push(scale(item));
		});

		return result;
	}

	for(let i = 0; i < teachers.length; i++) {
		// 计算主观题型比例
		let subjective = type[i].result;
		let	sScale = subjective !== '0'? Math.round((count[i].result - subjective) / subjective): count[i].result;

		result[i] = [];
		result[i].push(teachers[i].show_name);
		result[i].push(teachers[i].result);
		result[i].push(homework[i].result);
		result[i].push(Math.round(count[i].result / homework[i].result));
		result[i].push(Math.round(count[i].result / homework[i].result / timespan * 7));
		result[i].push(`${subjective !== '0'? 1: 0}:${sScale}`);
	}

	let diff = countDifficultyScale(difficulty);
	result.forEach((item, index) => result[index].splice(5, 0, diff[index]));

	return result;
}

/**
 * 根据提供的表名与字段名创建查询参数
 * @private
 * @param  {String} title     表名
 * @param  {String} field     字段名
 * @param  {String} startDate 开始日期
 * @param  {String} endDate   结束日期
 * @param  {array}  subjects  科目数组
 * @param  {array}  grades    年级数组
 * @param  {String} tableName 学科、年级查询表名
 * @return {DataAccessor}           数据访问参数对象
 */
function getObjectsByTitle(title, field, dataType, startDate, endDate, subjects, grades, tableName = TEACHER) {
	let dao = new DataAccessor(title, field)
		.dateRange(startDate, endDate)
		.dataType(dataType)
		.timeUnit(ENUM_TIME_UNIT.NONE);

	if (subjects && subjects.length)
		dao.subject(subjects, tableName);
	if (grades && grades.length)
		dao.grade(grades, tableName);

	return dao;
}

/**
 * 获得拥有基础结构的查询参数, 可以进一步构建查询参数
 * @private
 * @param     {String}                 startDate 开始时间
 * @param     {String}                 endDate   结束时间
 * @param     {String}                 subjects  学科
 * @param     {String}                 grades    年级
 * @return    {Array}                            筛选器查询参数数组
 */
function getObjects (startDate, endDate, subjects, grades) {
	// 教师数
	let teachers = getObjectsByTitle(HOMEWORK, `${TEACHER}_id`, ENUM_DATA_TYPE.COUNT, startDate, endDate, subjects, grades);
	// 作业数量
	let homework = getObjectsByTitle(HOMEWORK, `${HOMEWORK}_id`, ENUM_DATA_TYPE.COUNT, startDate,endDate, subjects, grades);
	// 作业题量
	let count = getObjectsByTitle(HOMEWORK, COUNT, ENUM_DATA_TYPE.SUM, startDate, endDate, subjects, grades);
	// 题目难度
	let difficulty = getObjectsByTitle(QUESTION, `question_id`, ENUM_DATA_TYPE.COUNT, startDate, endDate, subjects, grades);
	// 题目类型
	let type = getObjectsByTitle(HOMEWORK, TYPE, ENUM_DATA_TYPE.SUM, startDate, endDate, subjects, grades);
	// 布置周期
	let day = getObjectsByTitle(HOMEWORK, `${HOMEWORK}_id`, ENUM_DATA_TYPE.COUNT, startDate, endDate, subjects, grades);
	// 布置时段
	let hour = getObjectsByTitle(HOMEWORK, `${HOMEWORK}_id`, ENUM_DATA_TYPE.COUNT, startDate, endDate, subjects, grades);
	// 题目数量
	let question = getObjectsByTitle(QUESTION, `question_id`, ENUM_DATA_TYPE.COUNT, startDate, endDate, subjects, grades);

	return [teachers, homework, count, difficulty, type, day, hour, question];
}

/**
 * 获取城市视图查询参数
 * @private
 * @param     {String}                 cityId     城市ID
 * @param     {String}                 provinceId 省ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getCityData (cityId, provinceId, subjects, grades, startDate, endDate) {
	let cityData = getObjects(startDate, endDate, subjects, grades);
	let provinceData = cloneDeep(cityData);

	// 添加城市标识和省份标识
	cityData = cityData.map((item) => item.city(cityId, TEACHER));
	provinceData = provinceData.map((item) => item.province(provinceId, TEACHER));

	return [...cityData, ...provinceData];
}

/**
 * 获取区县视图查询参数
 * @private
 * @param     {String}                 cityId     城市ID
 * @param     {String}                 countyId   区县ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getCountyData (countyId, cityId, subjects, grades, startDate, endDate) {
	let countyData = getObjects(startDate, endDate, subjects, grades);
	let cityData = cloneDeep(countyData);

	// 添加城市标识和区县标识
	countyData = countyData.map((item) => item.county(countyId, TEACHER));
	cityData = cityData.map((item) => item.city(cityId, TEACHER));

	return [...countyData, ...cityData];
}

/**
 * 获取学校视图查询参数
 * @private
 * @param     {String}                 schoolId   学校ID
 * @param     {String}                 countyId   区县ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getSchoolData (schoolId, countyId, subjects, grades, startDate, endDate) {
	let schoolData = getObjects(startDate, endDate, subjects, grades);
	let countyData = cloneDeep(schoolData);

	// 添加城市标识和区县标识
	schoolData = schoolData.map((item) => item.school(schoolId, TEACHER));
	countyData = countyData.map((item) => item.county(countyId, TEACHER));

	return [...schoolData, ...countyData];
}

/**
 * @description 布置作业城市视图基础数据
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceId   省ID
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String} 				   options.startDate 	开始日期
 * @param     {String} 				   options.endDate 		结束日期
 * @return    {Promise}                                     基础数据
 */
export function viewCity ({ cityId, cityName, provinceId, provinceName, subjects, grades, startDate, endDate, timespan }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = packageListData(cityName, provinceName, timespan, result.data);

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}
			return result;
		});
};

/**
 * @description 布置作业区县视图基础数据
 * @public
 * @param     {String}                 options.countyId   区县id
 * @param     {String}                 options.countyName 区县名
 * @param     {String}                 options.cityId	  城市名
 * @param     {String}                 options.cityName   城市名
 * @param     {String}                 options.subjects   学科
 * @param     {String}                 options.grades     年级
 * @param     {String}                 options.startDate  开始时间
 * @param     {String}                 options.endDate    结束时间
 * @param     {String}                 options.timespan   时间跨度
 * @return    {Promise}                                   基础数据
 */
export function viewCounty ({ countyId, countyName, cityId, cityName, subjects, grades, startDate, endDate, timespan}) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = packageListData(countyName, cityName, timespan, result.data);

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}
			return result;
		});
};

/**
 * @description 布置作业学校视图基础数据
 * @public
 * @param     {String}                 options.schoolId   学校id
 * @param     {String}                 options.schoolName 学校名
 * @param     {String}                 options.countyId   区县名
 * @param     {String}                 options.countyName 区县名
 * @param     {String}                 options.subjects   学科
 * @param     {String}                 options.grades     年级
 * @param     {String}                 options.startDate  开始时间
 * @param     {String}                 options.endDate    结束时间
 * @param     {String}                 options.timespan   时间跨度
 * @return    {Promise}                                   基础数据
 */
export function viewSchool ({ countyId, countyName, schoolId, schoolName, subjects, grades, startDate, endDate, timespan}) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = packageListData(schoolName, countyName, timespan, result.data);

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}
			return result;
		});
};

/**
 * 获取城市视图教师周布置频次
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId   省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @param     {Number}                 options.timespan     时间跨度
 * @return    {Promise}
 */
export function getCityFrequency ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate, timespan, group = 'subject' }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[0], dataObjects[1], dataObjects[8], dataObjects[9]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [teachers, homework, parentTeachers, parentHomework] = result.data;
				let data = [[], [], []];

				teachers.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(homework[index].result / teachers[index].result / timespan * 7));
					data[2].push(Math.round(parentHomework[index].result / parentTeachers[index].result / timespan * 7));
				});
				data[3] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图教师周布置频次
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId	    城市ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @param     {Number}                 options.timespan     时间跨度
 * @return    {Promise}
 */
export function getCountyFrequency ({ countyId, cityId, cityName, countyName, subjects, grades, startDate, endDate, timespan, group = 'subject' }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[0], dataObjects[1], dataObjects[8], dataObjects[9]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [teachers, homework, parentTeachers, parentHomework] = result.data;
				let data = [[], [], []];

				teachers.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(homework[index].result / teachers[index].result / timespan * 7));
					data[2].push(Math.round(parentHomework[index].result / parentTeachers[index].result / timespan * 7));
				});
				data[3] = [countyName, cityName];
				
				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图教师周布置频次
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId	    区县ID
 * @param     {String}                 options.schoolName   学校名名
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @param     {Number}                 options.timespan     时间跨度
 * @return    {Promise}
 */
export function getSchoolFrequency ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate, timespan, group = 'subject' }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[0], dataObjects[1], dataObjects[8], dataObjects[9]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [teachers, homework, parentTeachers, parentHomework] = result.data;
				let data = [[], [], [], []];

				teachers.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(homework[index].result / teachers[index].result / timespan * 7));
					data[2].push(Math.round(parentHomework[index].result / parentTeachers[index].result / timespan * 7));
				});
				data[3] = [schoolName, countyName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图教师平均作业量
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId	省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @return    {Promise}
 */
export function getCityAverage ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate, group = 'subject' }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[2], dataObjects[9], dataObjects[10]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, count, parentHomework, parentCount] = result.data;
				let data = [[], [], [], []];

				homework.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(count[index].result / homework[index].result));
					data[2].push(Math.round(parentCount[index].result / parentHomework[index].result));
				});
				data[3] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图教师平均作业量
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId	    城市ID
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.cityName 	城市名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @return    {Promise}
 */
export function getCountyAverage ({ countyId, cityId, countyName, cityName, subjects, grades, startDate, endDate, group = 'subject' }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[2], dataObjects[9], dataObjects[10]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, count, parentHomework, parentCount] = result.data;
				let data = [[], [], [], []];

				homework.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(count[index].result / homework[index].result));
					data[2].push(Math.round(parentCount[index].result / parentHomework[index].result));
				});
				data[3] = [countyName, cityName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图教师平均作业量
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId	    区县ID
 * @param     {String}                 options.schoolName   学校名
 * @param     {String}                 options.countyName 	区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @param     {String}                 options.group        分组
 * @return    {Promise}
 */
export function getSchoolAverage ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate, group = 'subject' }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[2], dataObjects[9], dataObjects[10]];
	data = data.map((item) => {
		item.multiUnit(`${TEACHER}-${group}`);
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, count, parentHomework, parentCount] = result.data;
				let data = [[], [], [], []];

				homework.forEach((item, index) => {
					data[0].push(item.show_name);
					data[1].push(Math.round(count[index].result / homework[index].result));
					data[2].push(Math.round(parentCount[index].result / parentHomework[index].result));
				});
				data[3] = [schoolName, countyName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图难度分布
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId	省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCityDifficulty ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[3], dataObjects[7], dataObjects[11], dataObjects[15]];
	data = data.map((item, index) => {
		if(index % 2 === 0) { item.multiUnit(`${QUESTION}-${DIFFICULTY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [difficulty, question, parentDifficulty, parentQuestion] = result.data;
				let data = [[], [], []];

				// 剔除multi_data=0的数据
				if(difficulty[0].multi_data === '0') question[0].result -= difficulty[0].result;
				if(parentDifficulty[0].multi_data === '0') parentQuestion[0].result -= parentDifficulty[0].result;
				difficulty = difficulty.filter((item) => item.multi_data !== '0');
				parentDifficulty = parentDifficulty.filter((item) => item.multi_data !== '0');

				// 补全难度分布
				let newDifficulty = [];
				let newParentDifficulty = [];
				for(let i = 1; i <= 4; i++) {
					newDifficulty.push({ multi_data: i, result: 0 });
					newParentDifficulty.push({ multi_data: i, result: 0 });
				}
				difficulty.forEach((item, index) => {
					if(item.multi_data != 0 ) {
						let i = Number(item.multi_data);
						newDifficulty[i - 1].result = Number(difficulty[index].result);
						newParentDifficulty[i - 1].result = Number(parentDifficulty[index].result);
					}
				});
				newDifficulty.forEach((item, index) => {
					data[0].push((newDifficulty[index].result / question[0].result).toFixed(2) * 100);
					data[1].push((newParentDifficulty[index].result / parentQuestion[0].result).toFixed(2) * 100);
				});
				data[2] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图难度分布
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId		城市ID
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.cityName 	城市名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCountyDifficulty ({ countyId, cityId, countyName, cityName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[3], dataObjects[7], dataObjects[11], dataObjects[15]];
	data = data.map((item, index) => {
		if(index % 2 === 0) { item.multiUnit(`${QUESTION}-${DIFFICULTY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [difficulty, question, parentDifficulty, parentQuestion] = result.data;
				let data = [[], [], []];

				// 剔除multi_data=0的数据
				if(difficulty[0].multi_data === '0') question[0].result -= difficulty[0].result;
				if(parentDifficulty[0].multi_data === '0') parentQuestion[0].result -= parentDifficulty[0].result;
				difficulty = difficulty.filter((item) => item.multi_data !== '0');
				parentDifficulty = parentDifficulty.filter((item) => item.multi_data !== '0');

				// 补全难度分布
				let newDifficulty = [];
				let newParentDifficulty = [];
				for(let i = 1; i <= 4; i++) {
					newDifficulty.push({ multi_data: i, result: 0 });
					newParentDifficulty.push({ multi_data: i, result: 0 });
				}
				difficulty.forEach((item, index) => {
					if(item.multi_data != 0 ) {
						let i = Number(item.multi_data);
						newDifficulty[i - 1].result = Number(difficulty[index].result);
						newParentDifficulty[i - 1].result = Number(parentDifficulty[index].result);
					}
				});
				newDifficulty.forEach((item, index) => {
					data[0].push((newDifficulty[index].result / question[0].result).toFixed(2) * 100);
					data[1].push((newParentDifficulty[index].result / parentQuestion[0].result).toFixed(2) * 100);
				});
				data[2] = [countyName, cityName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图难度分布
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId		区县ID
 * @param     {String}                 options.schoolName   学校名
 * @param     {String}                 options.countyName 	区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getSchoolDifficulty ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[3], dataObjects[7], dataObjects[11], dataObjects[15]];
	data = data.map((item, index) => {
		if(index % 2 === 0) { item.multiUnit(`${QUESTION}-${DIFFICULTY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [difficulty, question, parentDifficulty, parentQuestion] = result.data;
				let data = [[], [], []];

				// 剔除multi_data=0的数据
				if(difficulty[0].multi_data === '0') question[0].result -= difficulty[0].result;
				if(parentDifficulty[0].multi_data === '0') parentQuestion[0].result -= parentDifficulty[0].result;
				difficulty = difficulty.filter((item) => item.multi_data !== '0');
				parentDifficulty = parentDifficulty.filter((item) => item.multi_data !== '0');

				// 补全难度分布
				let newDifficulty = [];
				let newParentDifficulty = [];
				for(let i = 1; i <= 4; i++) {
					newDifficulty.push({ multi_data: i, result: 0 });
					newParentDifficulty.push({ multi_data: i, result: 0 });
				}
				difficulty.forEach((item, index) => {
					if(item.multi_data != 0 ) {
						let i = Number(item.multi_data);
						newDifficulty[i - 1].result = Number(difficulty[index].result);
						newParentDifficulty[i - 1].result = Number(parentDifficulty[index].result);
					}
				});
				newDifficulty.forEach((item, index) => {
					data[0].push((newDifficulty[index].result / question[0].result).toFixed(2) * 100);
					data[1].push((newParentDifficulty[index].result / parentQuestion[0].result).toFixed(2) * 100);
				});
				data[2] = [schoolName, countyName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图题型分布
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId	省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCityQuestionType ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[2], dataObjects[4], dataObjects[10], dataObjects[12]];
	data = data.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [count, type, parentCount, parentType] = result.data;
				let data = [[], [], []];

				data[0].push((type[0].result / count[0].result).toFixed(2) * 100);
				data[1].push((parentType[0].result / parentCount[0].result).toFixed(2) * 100);
				data[2] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图题型分布
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId		城市ID
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.cityName 	城市名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCountyQuestionType ({ countyId, cityId, countyName, cityName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[2], dataObjects[4], dataObjects[10], dataObjects[12]];
	data = data.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [count, type, parentCount, parentType] = result.data;
				let data = [[], [], []];

				data[0].push((type[0].result / count[0].result).toFixed(2) * 100);
				data[1].push((parentType[0].result / parentCount[0].result).toFixed(2) * 100);
				data[2] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图题型分布
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId		区县ID
 * @param     {String}                 options.schoolName   学校名
 * @param     {String}                 options.countyName 	区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getSchoolQuestionType ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[2], dataObjects[4], dataObjects[10], dataObjects[12]];
	data = data.map((item) => item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject());

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [count, type, parentCount, parentType] = result.data;
				let data = [[], [], []];

				data[0].push((type[0].result / count[0].result).toFixed(2) * 100);
				data[1].push((parentType[0].result / parentCount[0].result).toFixed(2) * 100);
				data[2] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图布置周期
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId	省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCityPeriod ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[5], dataObjects[9], dataObjects[13]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${DAY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, day, parentHomework, parentDay] = result.data;
				let data = [[], [], [], []];

				day.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push((day[index].result / homework[0].result).toFixed(4) * 100);
					data[2].push((parentDay[index].result / parentHomework[0].result).toFixed(4) * 100);
				});
				data[3] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图布置周期
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId		城市ID
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.cityName 	城市名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCountyPeriod ({ countyId, cityId, countyName, cityName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[5], dataObjects[9], dataObjects[13]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${DAY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, day, parentHomework, parentDay] = result.data;
				let data = [[], [], [], []];

				day.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push((day[index].result / homework[0].result).toFixed(4) * 100);
					data[2].push((parentDay[index].result / parentHomework[0].result).toFixed(4) * 100);
				});
				data[3] = [countyName, cityName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图布置周期
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId		区县ID
 * @param     {String}                 options.schoolName   学校名
 * @param     {String}                 options.countyName 	区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getSchoolPeriod ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[5], dataObjects[9], dataObjects[13]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${DAY}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, day, parentHomework, parentDay] = result.data;
				let data = [[], [], [], []];

				day.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push((day[index].result / homework[0].result).toFixed(4) * 100);
					data[2].push((parentDay[index].result / parentHomework[0].result).toFixed(4) * 100);
				});
				data[3] = [schoolName, countyName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图时段分布
 * @public
 * @param     {String}                 options.cityId       城市ID
 * @param     {String}                 options.provinceId	省ID
 * @param     {String}                 options.cityName     城市名
 * @param     {String}                 options.provinceName 省名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCityTimeround ({ cityId, provinceId, cityName, provinceName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[6], dataObjects[9], dataObjects[14]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${HOUR}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, hour, parentHomework, parentHour] = result.data;

				// 补全时段
				let newHour = [];
				let newParentHour = [];
				for(let i = 0; i < 24; i++) {
					newHour.push({ multi_data: i, result: 0 });
					newParentHour.push({ multi_data: i, result: 0 });
				}
				hour.forEach((item, index) => {
					let i = Number(item.multi_data);
					newHour[i].result = Number(hour[index].result);
					newParentHour[i].result = Number(parentHour[index].result);
				});

				let data = [[], [], [], []];
				newHour.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push(newHour[index].result);
					data[2].push(newParentHour[index].result);
				});
				data[3] = [cityName, provinceName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图时段分布
 * @public
 * @param     {String}                 options.countyId     区县ID
 * @param     {String}                 options.cityId		城市ID
 * @param     {String}                 options.countyName   区县名
 * @param     {String}                 options.cityName 	城市名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getCountyTimeround ({ countyId, cityId, countyName, cityName, subjects, grades, startDate, endDate }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[6], dataObjects[9], dataObjects[14]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${HOUR}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, hour, parentHomework, parentHour] = result.data;

				// 补全时段
				let newHour = [];
				let newParentHour = [];
				for(let i = 0; i < 24; i++) {
					newHour.push({ multi_data: i, result: 0 });
					newParentHour.push({ multi_data: i, result: 0 });
				}
				hour.forEach((item, index) => {
					let i = Number(item.multi_data);
					newHour[i].result = Number(hour[index].result);
					newParentHour[i].result = Number(parentHour[index].result);
				});

				let data = [[], [], [], []];
				newHour.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push(newHour[index].result);
					data[2].push(newParentHour[index].result);
				});
				data[3] = [countyName, cityName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图时段分布
 * @public
 * @param     {String}                 options.schoolId     学校ID
 * @param     {String}                 options.countyId		区县ID
 * @param     {String}                 options.schoolName   学校名
 * @param     {String}                 options.countyName 	区县名
 * @param     {String}                 options.subjects     学科
 * @param     {String}                 options.grades       年级
 * @param     {String}                 options.startDate    开始时间
 * @param     {String}                 options.endDate      结束时间
 * @return    {Promise}
 */
export function getSchoolTimeround ({ schoolId, countyId, schoolName, countyName, subjects, grades, startDate, endDate }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	let data = [dataObjects[1], dataObjects[6], dataObjects[9], dataObjects[14]];
	data = data.map((item, index) => {
		if(index % 2 === 1) { item.multiUnit(`${HOMEWORK}-${HOUR}`); }
		return item.timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, data)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let [homework, hour, parentHomework, parentHour] = result.data;

				// 补全时段
				let newHour = [];
				let newParentHour = [];
				for(let i = 0; i < 24; i++) {
					newHour.push({ multi_data: i, result: 0 });
					newParentHour.push({ multi_data: i, result: 0 });
				}
				hour.forEach((item, index) => {
					let i = Number(item.multi_data);
					newHour[i].result = Number(hour[index].result);
					newParentHour[i].result = Number(parentHour[index].result);
				});

				let data = [[], [], [], []];
				newHour.forEach((item, index) => {
					data[0].push(item.multi_data);
					data[1].push(newHour[index].result);
					data[2].push(newParentHour[index].result);
				});
				data[3] = [schoolName, countyName];

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取城市视图数据详情
 * @public
 * @param     {String}                 options.cityId     城市ID
 * @param     {String}                 options.cityName   城市名
 * @param     {String}                 options.subjects   学科
 * @param     {String}                 options.grades     年级
 * @param     {String}                 options.startDate  开始时间
 * @param     {String}                 options.endDate    结束时间
 * @param     {String}                 options.sortBy     排序字段
 * @param     {String}                 options.desc       正反序
 * @param     {Number}                 options.timespan   时间跨度
 * @return    {Promise}                                   数据详情
 */
export function getCityDetail ({ cityId, subjects, grades, startDate, endDate, sortBy = 'teacher', desc = true, timespan }) {
	let dataObjects = getObjects(startDate, endDate, subjects, grades);
	dataObjects = dataObjects.map((item, index) => {
		if(index === 3) item.multiUnitEx(`${QUESTION}-${DIFFICULTY}`);
		return item.city(cityId, TEACHER).multiUnit(`${TEACHER}-county_id`).timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = packageDetail(timespan, result.data);
 				
 				switch (sortBy) {
 					case 'teacher':
 						data = data.sort((a, b) => a[1] - b[1]);
 						break;
 					case 'homework':
 						data = data.sort((a, b) => a[2] - b[2]);
 						break;
 					case 'average':
 						data = data.sort((a, b) => a[3] - b[3]);
 						break;
 					case 'frequency':
 						data = data.sort((a, b) => a[4] - b[4]);
 						break;
 				}

 				if(desc) data = data.reverse();

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图数据详情
 * @public
 * @param     {String}                 options.countyId   区县ID
 * @param     {String}                 options.countyName 区县名
 * @param     {String}                 options.subjects   学科
 * @param     {String}                 options.grades     年级
 * @param     {String}                 options.startDate  开始时间
 * @param     {String}                 options.endDate    结束时间
 * @param     {String}                 options.sortBy     排序字段
 * @param     {String}                 options.desc       正反序
 * @param     {Number}                 options.timespan   时间跨度
 * @return    {Promise}                                   数据详情
 */
export function getCountyDetail ({ countyId, subjects, grades, startDate, endDate, sortBy = 'teacher', desc = true, timespan }) {
	let dataObjects = getObjects(startDate, endDate, subjects, grades);
	dataObjects = dataObjects.map((item, index) => {
		if(index === 3) item.multiUnitEx(`${QUESTION}-${DIFFICULTY}`);
		return item.county(countyId, TEACHER).multiUnit(`${TEACHER}-school_id`).timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = packageDetail(timespan, result.data);
 				
 				switch (sortBy) {
 					case 'teacher':
 						data = data.sort((a, b) => a[1] - b[1]);
 						break;
 					case 'homework':
 						data = data.sort((a, b) => a[2] - b[2]);
 						break;
 					case 'average':
 						data = data.sort((a, b) => a[3] - b[3]);
 						break;
 					case 'frequency':
 						data = data.sort((a, b) => a[4] - b[4]);
 						break;
 				}

 				if(desc) data = data.reverse();
 				
				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};




